package com.cl.short_video_java.handler;

import com.cl.short_video_java.common.Result;
import com.cl.short_video_java.exception.WebException;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.MyBatisSystemException;
import org.springframework.http.HttpStatus;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.sql.SQLNonTransientConnectionException;
import java.sql.SQLSyntaxErrorException;

/**
 * @Author 付
 * @Date 2024-03-14 17:59
 * @Version 1.0
 * @description
 * @since 1.0
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
	@ExceptionHandler(value = WebException.class)
	@ResponseStatus(HttpStatus.BAD_REQUEST)
	public Result handler(WebException webException) {
		log.error("出现自定义异常(状态异常)------->" + webException);
		return Result.error(webException.getMessage(), webException.getCode());
	}

	@ExceptionHandler(value = Exception.class)
	@ResponseStatus(HttpStatus.BAD_REQUEST)
	public Result handler(Exception e) {
		log.error("出现自定义异常(全局异常)------->" + e.getMessage());
		e.printStackTrace();
		return Result.error(e.getMessage());
	}

	@ExceptionHandler(value = NoHandlerFoundException.class)
	@ResponseStatus(HttpStatus.NOT_FOUND)
	public Result handler(NoHandlerFoundException e) {
		log.error("出现自定义异常(未创建异常)------->" + e.getMessage());
		e.printStackTrace();
		return Result.error("404！页面不存在", 404);
	}

	@ExceptionHandler(value = SQLNonTransientConnectionException.class)
	@ResponseStatus(HttpStatus.EXPECTATION_FAILED)
	public Result handler(SQLNonTransientConnectionException e) {
		log.error("出现自定义异常(数据库连接异常)------->" + e.getMessage());
		e.printStackTrace();
		return Result.error("数据库异常", 401);
	}

	@ExceptionHandler(value = CannotGetJdbcConnectionException.class)
	@ResponseStatus(HttpStatus.EXPECTATION_FAILED)
	public Result handler(CannotGetJdbcConnectionException e) {
		log.error("出现自定义异常(数据库连接异常)------->" + e.getMessage());
		e.printStackTrace();
		return Result.error("数据库异常", 401);
	}

	@ExceptionHandler(value = MyBatisSystemException.class)
	@ResponseStatus(HttpStatus.EXPECTATION_FAILED)
	public Result handler(MyBatisSystemException e) {
		log.error("出现自定义异常(数据库语法错误异常)------->" + e.getMessage());
		e.printStackTrace();
		return Result.error(e.getMessage(), 401);
	}

	@ExceptionHandler(value = BindException.class)
	@ResponseStatus(HttpStatus.NOT_FOUND)
	public Result handler(BindException e) {
		BindingResult bindingResult = e.getBindingResult();
		ObjectError objectError = bindingResult.getAllErrors().stream().findFirst().get();
		log.error("出现自定义异常(绑定异常)------->" + objectError.getDefaultMessage());
		e.printStackTrace();
		return Result.error(objectError.getDefaultMessage(), 404);
	}

    	// 拦截：缺少权限异常
	@ExceptionHandler(NotPermissionException.class)
	public SaResult handlerException(NotPermissionException e) {
		e.printStackTrace(); 
		return SaResult.error("缺少权限：" + e.getPermission());
	}

	// 拦截：缺少角色异常
	@ExceptionHandler(NotRoleException.class)
	public SaResult handlerException(NotRoleException e) {
		e.printStackTrace(); 
		return SaResult.error("缺少角色：" + e.getRole());
	}

	// 拦截：二级认证校验失败异常
	@ExceptionHandler(NotSafeException.class)
	public SaResult handlerException(NotSafeException e) {
		e.printStackTrace(); 
		return SaResult.error("二级认证校验失败：" + e.getService());
	}

	// 拦截：服务封禁异常 
	@ExceptionHandler(DisableServiceException.class)
	public SaResult handlerException(DisableServiceException e) {
		e.printStackTrace(); 
		return SaResult.error("当前账号 " + e.getService() + " 服务已被封禁 (level=" + e.getLevel() + ")：" + e.getDisableTime() + "秒后解封");
	}

	// 拦截：Http Basic 校验失败异常 
	@ExceptionHandler(NotHttpBasicAuthException.class)
	public SaResult handlerException(NotHttpBasicAuthException e) {
		e.printStackTrace(); 
		return SaResult.error(e.getMessage());
	}
}
